/*
----------------------------------------------------------------------------------------------------
This source file is part of the Gamut Framework
Copyright (c) 2007 by Ryan Holcombe

This program is free software; you can redistribute it and/or modify it under the terms of the GNU
Lesser General Public License as published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
----------------------------------------------------------------------------------------------------
*/


#ifndef _Profiler_h_
#define _Profiler_h_

#include "GamutTimer.h"
#include "Singleton.h"
#include <map>
#include <string>

#ifdef _DEBUG
	#define PROFILE_START(name)	Gamut::Profiler::getSingleton().startProfile(name)
	#define PROFILE_STOP(name)	Gamut::Profiler::getSingleton().stopProfile(name)
#else
	#define PROFILE_START(name)
	#define PROFILE_STOP(name)
#endif




namespace Gamut
{
	struct Profile;
	typedef std::map<std::string, Profile*> ProfileMap;

	/**
		struct which contains all recorded data for a single profile name
	*/

	struct Profile
	{
		//! minimum time spent on any single cnt
		double minTime;

		//! max time spent on any single cnt
		double maxTime;

		//! total time spent in the code block	
		double totalTime;

		//! number of times code block was involked
		int cnt;

		//! start time of the last PROFILE_START
		double _lastTime;
	};

	
	/**
 		Profiler will give descriptive information as to how much processing time
		if being spent on any given code block

		\remarks
			_DEBUG must be defined for profiles to be generated
	*/

	class Profiler : public Singleton<Profiler>
	{
	private:
		//! profile creation time
		Gamut::Timer mTimer;
		
		//! map of all created profiles
		ProfileMap mProfile;

	public:
		/** Default constructor
			\brief creates a profiler singleton, game time starts on creation
		*/
		Profiler();
			
		
		/** Default deconstructor
			\brief stops the time, and logs all profile results
		*/
		~Profiler();
		
		
		/**
			\brief begins a profile or adds another entry onto an existing one
		*/
		void startProfile(std::string name);
		
		
		/**
			\brief stop and record the currently running profile
		*/
		void stopProfile(std::string name);	
	};
	
}



#endif
